class MyDatabase {
  constructor() {
    this.dbIns = null
    this.tempProLs = {
      res: null,
      rej: null
    }
    this.isConnected = false
  }
  /**
   * 链接数据库，返回数据库实例
   * @param {string} type
   * @returns {Promise}
   */
  connect() {
    // 链接消息存储数据库
    let request = window.indexedDB.open('myDatabase', 1)
    request.onsuccess = (e) => {
      this.connectSuccess(e)
    }
    request.onerror = (e) => {
      this.connectFailed(e)
    }
    request.onupgradeneeded = function (event) {
      let db = event.target.result
      console.log('数据库', db)
      //   创建一个存储消息的表
      if (!db.objectStoreNames.contains('message')) {
        let objectStore = db.createObjectStore('message', { keyPath: 'timestamp' })
        objectStore.createIndex('timestamp', 'timestamp', { unique: false })
        // // 比对的车牌信息1
        // objectStore.createIndex('composition1', 'composition1', { unique: false })
        // // 比对的车牌信息2
        // objectStore.createIndex('composition2', 'composition2', { unique: false })
        // // 比对时间
        // objectStore.createIndex('timestamp', 'timestamp', { unique: false })
        // // 比对是否成功
        // objectStore.createIndex('isSame', 'isSame', { unique: false })
      }
      //   创建一个存储计数的表
      if (!db.objectStoreNames.contains('count')) {
        db.createObjectStore('count')
      }
    }
    return new Promise((res, rej) => {
      this.tempProLs.res = res
      this.tempProLs.rej = rej
    })
  }
  //   链接成功，存储数据库对象实例
  connectSuccess(event) {
    console.log('数据库连接成功')
    this.isConnected = true
    this.dbIns = event.target.result
    this.tempProLs.res()
    this.tempProLs = {
      res: null,
      rej: null
    }
  }
  //   连接失败
  connectFailed() {
    console.log('数据库连接失败')
    this.isConnected = false
    this.tempProLs.rej()
    this.tempProLs = {
      res: null,
      rej: null
    }
  }
  //   获取某个表的存储对象，后续对数据库操作都基于此对象
  getObjectStore(storeName) {
    const transaction = this.dbIns.transaction([storeName], 'readwrite')
    const store = transaction.objectStore(storeName)
    return store
  }
  // 获取某个时间范围内的数据，需要时间戳
  getRangeData(startDate, endDate, lastDays) {
    return new Promise((resolve, reject) => {
      let objectStore = this.getObjectStore('message')
      let range = null
      // 如果存在要统计最近多少天的数据
      if (lastDays) {
        const oneWeekAgo = new Date()
        oneWeekAgo.setDate(oneWeekAgo.getDate() - lastDays)
        const oneWeekAgoTimestamp = oneWeekAgo.getTime()
        range = IDBKeyRange.lowerBound(oneWeekAgoTimestamp)
      } else {
        // 创建一个时间范围
        range = IDBKeyRange.bound(startDate, endDate)
      }

      // 根据这个时间范围，打开游标进行搜索
      let cursorRequest = objectStore.openCursor(range)

      let stats = []
      // 每次游标搜索成功，将符合范围的数据添加到数据组中
      cursorRequest.onsuccess = function (event) {
        let cursor = event.target.result
        if (cursor) {
          // 如果timestamp在最近一周内，添加到结果数组
          stats.push(cursor.value)
          cursor.continue()
        } else {
          resolve(stats)
        }
      }

      cursorRequest.onerror = function (event) {
        reject('Error opening cursor')
      }
    })
  }
  // 删除对应日期数据
  deleteRangeData(startDate, endDate, lastDays) {
    return new Promise((resolve, reject) => {
      let objectStore = this.getObjectStore('message')
      let range = null
      // 如果存在要删除最近多少天的数据
      if (lastDays) {
        const oneWeekAgo = new Date()
        oneWeekAgo.setDate(oneWeekAgo.getDate() - lastDays)
        const oneWeekAgoTimestamp = oneWeekAgo.getTime()
        range = IDBKeyRange.lowerBound(oneWeekAgoTimestamp)
      } else {
        // 创建一个时间范围
        range = IDBKeyRange.bound(startDate, endDate)
      }

      // 根据这个时间范围，打开游标进行搜索
      let cursorRequest = objectStore.openCursor(range)

      cursorRequest.onsuccess = function (event) {
        let cursor = event.target.result
        if (cursor) {
          // 删除当前游标指向的数据
          cursor.delete()
          cursor.continue()
        } else {
          resolve()
        }
      }

      cursorRequest.onerror = function (event) {
        reject('Error opening cursor')
      }
    })
  }
  // 删除所有数据
  deleteAllData() {
    return new Promise((resolve, reject) => {
      let objectStore = this.getObjectStore('message')
      let deleteReq = objectStore.clear()
      deleteReq.onsuccess = function (event) {
        resolve()
      }
      deleteReq.onerror = function (event) {
        reject()
      }
    })
  }
  // 获取所有数据
  async getAllData() {
    let transaction = this.dbIns.transaction(['message'], 'readonly')
    let objectStore = transaction.objectStore('message')
    let getAllreq = objectStore.getAll()

    return await new Promise((resolve, reject) => {
      getAllreq.onsuccess = function (event) {
        let allData = event.target.result
        if (allData) {
          resolve(allData)
        } else {
          resolve([])
        }
      }
      getAllreq.onerror = function (event) {
        resolve([])
      }
    })
  }
  // 获取某个日期之前的数据
  getBeforeDateData(date) {
    return new Promise((resolve, reject) => {
      let objectStore = this.getObjectStore('message')
      const range = IDBKeyRange.upperBound(date, false)
      let cursorReq = objectStore.openCursor(range)
      let stats = []
      cursorReq.onsuccess = function (event) {
        let cursor = event.target.result
        if (cursor) {
          // 如果timestamp在最近一周内，添加到结果数组
          stats.push(cursor.value)
          cursor.continue()
        } else {
          resolve(stats)
        }
      }
      cursorReq.onerror = function (event) {
        reject([])
      }
    })
  }
  // 根据自定义判断，删除某个日期之前的数据
  deleteBeforeDateData(date, cb) {
    return new Promise((resolve, reject) => {
      let objectStore = this.getObjectStore('message')
      const range = IDBKeyRange.upperBound(date, false)
      let cursorReq = objectStore.openCursor(range)
      cursorReq.onsuccess = function (event) {
        let cursor = event.target.result
        if (cursor) {
          // 通过回调返回，判断是否删除该数据
          if (cb(cursor.value)) {
            cursor.delete()
          } else {
            cursor.continue()
          }
        } else {
          resolve()
        }
      }
      cursorReq.onerror = function (event) {
        reject()
      }
    })
  }
}
const singleIns = new MyDatabase()
export default singleIns
